/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package izsla.beans;

import izsla.entities.LodgingType;
import izsla.entities.Trip;
import izsla.entities.TripUser;
import izsla.sb.TripManagementLocal;
import izsla.sb.UserManagementLocal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 *
 * @author aki
 */
public class NewTrip {
    // REQ5

    @EJB
    private TripManagementLocal tm;
    @EJB
    private UserManagementLocal um;
    private String description = "";
    private Date from;
    private Date to;
    private String mapURL;
    private int dist;
    private int limit;
    private String[] lodgingTypes;
    private String[] lodgingTypeList={"Hotel", "Motel", "Tent", "Nature", "Other"};
    private long lodgementId;

    public NewTrip() {
        from = to = new Date();
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Date getFrom() {
        return from;
    }

    public void setFrom(Date from) {
        this.from = from;
    }

    public Date getTo() {
        return to;
    }

    public void setTo(Date to) {
        this.to = to;
    }

    public String getMapURL() {
        return mapURL;
    }

    /**
     * Sets the google map link.
     * This must be the "link" of the map, not the " HTML code".
     */
    public void setMapURL(String mapURL) {
        this.mapURL = mapURL;
    }

    public long getLodgementId() {
        return lodgementId;
    }

    public void setLodgementId(long lodgementId) {
        this.lodgementId = lodgementId;
    }

    public String[] getLodgingTypes() {
        return lodgingTypes;
    }

    public void setLodgingTypes(String[] lodgingTypess) {
        System.out.print("\n\n number of lodgings: " + lodgingTypess.length + "\n\n");
        boolean isValidLodging=true;
        for(String lodging : lodgingTypess) {
            boolean valid = false;
            for(String validLodging : lodgingTypeList) {
                if(validLodging.equals(lodging) == true)
                    valid = true;
            }
            if (valid == false)
                isValidLodging = false;
        }
        // Cracking not occurs.
        if(isValidLodging != false)
            this.lodgingTypes = lodgingTypess;
    }

    public int getDist() {
        return dist;
    }

    public void setDist(int dist) {
        this.dist = dist;
    }

    public int getLimit() {
        return dist;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    /**
     * Trips length is valid between 0 and 50000 kms.
     */
    public void validateLength(FacesContext context, UIComponent component, Object input) {
        try {
            System.out.println("Length:" + input + "\t" + input.getClass());
            int len = (Integer) input;
            if (len < 0 || len > 50000) {
                throw new Exception();
            }
        } catch (Exception e) {
            throw new ValidatorException(new FacesMessage("Trip's length must be an integer between 0 and 50000!"));
        }
    }

    /**
     * The number of participants must be between 0 and 9999
     */
    public void validateLimit(FacesContext context, UIComponent component, Object input) {
        try {
            System.out.println("Limit:" + input + "\t" + input.getClass());
            int lim = (Integer) input;
            if (lim < 0 || lim > 9999) {
                throw new Exception();
            }
        } catch (Exception e) {
            throw new ValidatorException(new FacesMessage("Trip's limit must be an integer between 0 and 9999!"));
        }
    }

    /**
     * Adds a new trip. When the new trip is matched a criteria, the user is notified via e-mail.
     */
    public String addNewTrip() {
        Trip t = new Trip();
        t.setDescription(description);
        t.setStartTime(from);
        t.setEndTime(to);
        t.setMapURL(mapURL);
        t.setDistance(dist);
        t.setLimit(limit);
        t.setOrganiser(SessionHelper.getUser()); // REQ11

        System.out.print("Adding lodging types... " + lodgingTypes.length + " kinds.\n");
        ArrayList<LodgingType> lts = new ArrayList<LodgingType>();
        for(String ltStr : lodgingTypes) {
            System.out.print("Adding type: "  + ltStr + "\n");
            LodgingType lt = new LodgingType();
            lt.setName(ltStr);
            lt.setTrip(t);
            lts.add(lt);
        }
        t.setLodgingTypes(lts);

        System.out.print("Adding...");
        tm.addTrip(t);
        System.out.print("Added.\n");

        // REQ14
        for(TripUser tu : um.getUsersToNotify(t)) {
            if(tu.getId() != SessionHelper.getUser().getId()) {
                String plural = "";
                if (t.getLimit() > 1) plural += "s";
                String message ="" +
                        "Dear " + tu.getName() + ",\n" +
                        "\n" +
                        "We inform you that " + t.getOrganiser().getName() + " is organizing a new trip: " + t.getDescription() +
                        ". It will be held from " + t.getStartTime() + " to " + t.getEndTime() +
                        ". The limit is " + t.getLimit() + " person" + plural + ". Check out the website for further information!\n" +
                        "\n"+
                        "Yours sincerely,\n" +
                        "the Motorbike tour organization team";
                try {
                    sendEmail(tu.getEmail(), message, "New interesting motorbike tour!");
                } catch (Exception ex) {
                    System.err.print("Users are not notified, because something is wrong with the mail configuration.");
                }
                System.out.println("User " + tu.getName() + " should be notified!!!!!!!!!!!!!!!!");
            }
        }

        return "search";
    }

    /**
     * E-mail sending helper function.
     */
    private void sendEmail(String recipient, String text, String subject) throws Exception {

        try {

            Properties props = new Properties();

            props.put("mail.smtp.host", "localhost");   //  'localhost' for testing

            Session session = Session.getDefaultInstance(props, null);

            Message message = new MimeMessage(session);
            message.setFrom();
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(recipient, false));

            message.setSubject(subject);
            message.setText(text);

            // sends the email message:
            Transport.send(message);

        } catch (Exception e) {
            System.out.println("Message sending failed to: " + recipient);
        }
    }
}
